package com.ctosb.classviewer.clazz.util;

import com.ctosb.classviewer.ClassReader;
import com.ctosb.classviewer.clazz.ClassFile;
import com.ctosb.classviewer.clazz.cp.*;

import java.util.HashMap;
import java.util.Map;

/**
 * constant pool 解析器
 */
public class Cp_infoParse {

    /**
     * constant pool tag 值
     */
    public static final byte CONSTANT_Class = 7;
    public static final byte CONSTANT_Fieldref = 9;
    public static final byte CONSTANT_Methodref = 10;
    public static final byte CONSTANT_InterfaceMethodref = 11;
    public static final byte CONSTANT_String = 8;
    public static final byte CONSTANT_Integer = 3;
    public static final byte CONSTANT_Float = 4;
    public static final byte CONSTANT_Long = 5;
    public static final byte CONSTANT_Double = 6;
    public static final byte CONSTANT_NameAndType = 12;
    public static final byte CONSTANT_Utf8 = 1;
    public static final byte CONSTANT_MethodHandle = 15;
    public static final byte CONSTANT_MethodType = 16;
    public static final byte CONSTANT_InvokeDynamic = 18;

    private static Map<Byte, Class<? extends Cp_info>> map = new HashMap<>();

    static {
        map.put(CONSTANT_Class, CONSTANT_Class_info.class);
        map.put(CONSTANT_Fieldref, CONSTANT_Fieldref_info.class);
        map.put(CONSTANT_Methodref, CONSTANT_Methodref_info.class);
        map.put(CONSTANT_InterfaceMethodref, CONSTANT_InterfaceMethodref_info.class);
        map.put(CONSTANT_String, CONSTANT_String_info.class);
        map.put(CONSTANT_Integer, CONSTANT_Integer_info.class);
        map.put(CONSTANT_Float, CONSTANT_Float_info.class);
        map.put(CONSTANT_Long, CONSTANT_Long_info.class);
        map.put(CONSTANT_Double, CONSTANT_Double_info.class);
        map.put(CONSTANT_NameAndType, CONSTANT_NameAndType_info.class);
        map.put(CONSTANT_Utf8, CONSTANT_Utf8_info.class);
        map.put(CONSTANT_MethodHandle, CONSTANT_MethodHandle_info.class);
        map.put(CONSTANT_MethodType, CONSTANT_MethodType_info.class);
        map.put(CONSTANT_InvokeDynamic, CONSTANT_InvokeDynamic_info.class);
    }

    public static Cp_info newCpInfo(ClassReader classReader, ClassFile classFile) throws IllegalAccessException, InstantiationException {
        byte tag = classReader.readByte();
        Class<? extends Cp_info> clazz = map.get(tag);
        Cp_info cp_info = clazz.newInstance();
        cp_info.setTag(tag).parse(classReader, classFile);
        return cp_info;
    }
}
